
class Pagination {
  constructor (selector, options = {}) {
    // 范围元素
    this.ele = document.querySelector(selector)

    // 等待创建的元素
    this.first = null
    this.prev = null
    this.next = null
    this.last = null
    this.list = null
    this.inp = null
    this.btn = null

    // 一些分页器相关数据(默认值)
    this.pageInfo = {
      // 当前第几页
      current: 1,
      // 一页多少条
      pagesize: 12,
      // 一共多少页
      totalpage: 9
    }

    // 触发方法
    this.setOptions(options)
    this.setEleStyle()
    this.createEle()
    this.bindHtml()
    this.bindEvent()
  }

  // 调整信息
  setOptions (options) {
    // 设置当前第几页
    this.pageInfo.current = options.current || 1
    // 设置一页显示多少条
    this.pageInfo.pagesize = options.pagesize || 12
    // 设置一共多少页
    if (options.totalpage) {
      this.pageInfo.totalpage = options.totalpage
    } else {
      if (options.total) {
        this.pageInfo.totalpage = Math.ceil(options.total / this.pageInfo.pagesize)
      } else {
        this.pageInfo.totalpage = 9
      }
    }
    // 设置其他内容
    this.pageInfo.first = options.first || '首页'

    // options.a 是 100
    this.pageInfo.change = options.change || function () {}
  }

  // 设置 ele 元素的样式
  setEleStyle () {
    this.setStyles(this.ele, {
      width: '1000px',
      height: '40px',
      border: '1px solid #333',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      padding: 0
    })
  }

  // 生成元素
  createEle () {
    // 创建元素的同时要给他设置样式, 并且插入到 this.ele 内
    this.origin = document.createElement('p')
    this.setStyles(this.origin, {
      padding: '5px 10px',
      margin: '0px 10px',
      border: '1px solid #333',
      cursor: 'pointer'
    })
    // 1. first 元素
    this.first = this.origin.cloneNode(true)
    this.first.innerText = this.pageInfo.first
    this.first.name = 'first'
    this.ele.appendChild(this.first)

    // 2. prev 元素
    this.prev = this.origin.cloneNode(true)
    this.prev.innerText = '上一页'
    this.prev.name = 'prev'
    this.ele.appendChild(this.prev)

    // 3. list 元素
    this.list = document.createElement('ul')
    this.setStyles(this.list, { display: 'flex', padding: 0 })
    this.ele.appendChild(this.list)

    // 4. next 元素
    this.next = this.origin.cloneNode(true)
    this.next.innerText = '下一页'
    this.next.name = 'next'
    this.ele.appendChild(this.next)

    // 5. last 元素
    this.last = this.origin.cloneNode(true)
    this.last.innerText = '尾页'
    this.last.name = 'last'
    this.ele.appendChild(this.last)

    // 6. inp 元素
    this.inp = document.createElement('input')
    this.inp.value = this.pageInfo.current
    this.setStyles(this.inp, { width: '50px', height: '30px', textAlign: 'center', outline: 'none', margin: '0 10px' })
    this.ele.appendChild(this.inp)

    // 7. btn 元素
    this.btn = document.createElement('button')
    this.btn.innerText = '跳转'
    this.btn.name = 'go'
    this.setStyles(this.btn, { width: '50px', height: '34px', cursor: 'pointer' })
    this.ele.appendChild(this.btn)
  }

  // 根据分页信息, 创建对应的 li 插入到 this.list 内
  bindHtml () {
    // 0. 把信息提取出来
    const { current, totalpage } = this.pageInfo

    // 1. 根据当前是第几页, 决定首页和上一页的样式
    // 1-1. 准备一个禁用样式
    const disable = { backgroundColor: '#ccc', cursor: 'not-allowed' }
    const enable = { backgroundColor: '#fff', cursor: 'pointer' }
    // 1-2. 准备一个取消禁用样式
    if (current <= 1) {
      // 首页 和 上一页禁用
      this.setStyles(this.first, disable)
      this.setStyles(this.prev, disable)
    } else {
      // 首页 和 上一页取消禁用
      this.setStyles(this.first, enable)
      this.setStyles(this.prev, enable)
    }

    if (current >= totalpage) {
      // 尾页 和 下一页 禁用
      this.setStyles(this.next, disable)
      this.setStyles(this.last, disable)
    } else {
      // 尾页 和 下一页 取消禁用
      this.setStyles(this.next, enable)
      this.setStyles(this.last, enable)
    }

    // 2. 调整 inp 元素的 value
    this.inp.value = current

    // 3. 根据分页信息生成 li 渲染到 list 内
    this.bindList()

    // 4. 调用一下 change 函数
    this.pageInfo.change(this.pageInfo.current)
  }

  bindList () {
    // 清空 list 内容
    this.list.innerHTML = ''

    const { pagesize, current, totalpage } = this.pageInfo

    const origin = document.createElement('li')
    origin.dataset.name = 'item'
    this.setStyles(origin, { listStyle: 'none', border: '1px solid #333', padding: '5px 10px', margin: '0 5px', cursor: 'pointer' })

    // 情况1: 9 页以下的情况
    if (totalpage <= 9) {
      // 有多少页出现多少个 li 插入到 list 内
      for (let i = 0; i < totalpage; i++) {
        const li = origin.cloneNode(true)
        li.innerText = i + 1
        if (i + 1 === current) this.setStyles(li, { backgroundColor: 'orange', color: '#fff' })
        this.list.appendChild(li)
      }
      return
    }

    // 情况2: 9 页以上的情况
    // 情况2-1, 当前页小于 5
    if (current < 5) {
      for (let i = 0; i < 5; i++) {
        const li = origin.cloneNode(true)
        li.innerText = i + 1
        if (i + 1 === current) this.setStyles(li, { backgroundColor: 'orange', color: '#fff' })
        this.list.appendChild(li)
      }

      // 创建一个 span
      const span = document.createElement('span')
      span.innerText = '...'
      this.list.appendChild(span)

      for (let i = totalpage - 2; i < totalpage; i++) {
        const li = origin.cloneNode(true)
        li.innerText = i + 1
        this.list.appendChild(li)
      }

      return
    }

    // 方案2-2. 等于第五页
    if (current === 5) {
      for (let i = 0; i < 7; i++) {
        const li = origin.cloneNode(true)
        li.innerText = i + 1
        if (i + 1 === current) this.setStyles(li, { backgroundColor: 'orange', color: '#fff' })
        this.list.appendChild(li)
      }

      // 创建一个 span
      const span = document.createElement('span')
      span.innerText = '...'
      this.list.appendChild(span)

      for (let i = totalpage - 2; i < totalpage; i++) {
        const li = origin.cloneNode(true)
        li.innerText = i + 1
        this.list.appendChild(li)
      }

      return
    }

    // 方案2-3. 当前页大于倒数第五页
    if (current > totalpage - 4) {
      for (let i = 0; i < 2; i++) {
        const li = origin.cloneNode(true)
        li.innerText = i + 1
        this.list.appendChild(li)
      }

      // 创建一个 span
      const span = document.createElement('span')
      span.innerText = '...'
      this.list.appendChild(span)

      for (let i = totalpage - 5; i < totalpage; i++) {
        const li = origin.cloneNode(true)
        li.innerText = i + 1
        if (i + 1 === current) this.setStyles(li, { backgroundColor: 'orange', color: '#fff' })
        this.list.appendChild(li)
      }

      return
    }

    // 方案2-4: 当前页等于倒数第五页
    if (current === totalpage - 4) {
      for (let i = 0; i < 2; i++) {
        const li = origin.cloneNode(true)
        li.innerText = i + 1
        this.list.appendChild(li)
      }

      // 创建一个 span
      const span = document.createElement('span')
      span.innerText = '...'
      this.list.appendChild(span)

      for (let i = totalpage - 7; i < totalpage; i++) {
        const li = origin.cloneNode(true)
        li.innerText = i + 1
        if (i + 1 === current) this.setStyles(li, { backgroundColor: 'orange', color: '#fff' })
        this.list.appendChild(li)
      }

      return
    }

    // 方案2-5. 当前页在 第五页和倒数第五页之间
    for (let i = 0; i < 2; i++) {
      const li = origin.cloneNode(true)
      li.innerText = i + 1
      this.list.appendChild(li)
    }

    // 创建一个 span
    const span = document.createElement('span')
    span.innerText = '...'
    this.list.appendChild(span)

    for (let i = current - 3; i < current + 2; i++) {
      const li = origin.cloneNode(true)
      li.innerText = i + 1
      if (i + 1 === current) this.setStyles(li, { backgroundColor: 'orange', color: '#fff' })
      this.list.appendChild(li)
    }


    this.list.appendChild(span.cloneNode(true))

    for (let i = totalpage - 2; i < totalpage; i++) {
      const li = origin.cloneNode(true)
      li.innerText = i + 1
      this.list.appendChild(li)
    }
  }

  // 绑定点击事件
  bindEvent () {
    this.ele.addEventListener('click', e => {

      if (e.target.name === 'first') {
        if (this.pageInfo.current === 1) return
        // 把 pageinfo 内的 current 设置为 1
        this.pageInfo.current = 1
        // 重新渲染相关内容
        this.bindHtml()
      }

      if (e.target.name === 'prev') {
        // 如果当前就是第一页, 不需要
        if (this.pageInfo.current === 1) return
        // 把 pageinfo 内的 current 设置为 1
        this.pageInfo.current--
        // 重新渲染相关内容
        this.bindHtml()
      }

      if (e.target.name === 'next') {
        // 如果当前就是第一页, 不需要
        if (this.pageInfo.current === this.pageInfo.totalpage) return
        // 把 pageinfo 内的 current 设置为 1
        this.pageInfo.current++
        // 重新渲染相关内容
        this.bindHtml()
      }

      if (e.target.name === 'last') {
        // 如果当前就是第一页, 不需要
        if (this.pageInfo.current === this.pageInfo.totalpage) return
        // 把 pageinfo 内的 current 设置为 1
        this.pageInfo.current = this.pageInfo.totalpage
        // 重新渲染相关内容
        this.bindHtml()
      }

      if (e.target.name === 'go') {
        // 拿到 文本框 的内容
        let page = this.inp.value - 0

        if (isNaN(page)) page = 1
        if (page <= 1) page = 1
        if (page >= this.pageInfo.totalpage) page = this.pageInfo.totalpage

        // 赋值
        this.pageInfo.current = page
        // 重新渲染页面
        this.bindHtml()
      }

      if (e.target.dataset.name === 'item') {
        this.pageInfo.current = e.target.innerText - 0
        this.bindHtml()
      }
    })
  }

  // 准备一个功能函数
  // 专门用来给元素添加样式的
  setStyles (ele, styles) {
    // ele 是要添加样式的元素
    // styles 是一个对象 {}, 里面是要添加的样式

    // 遍历 styles 这个对象, 把每一项分别赋值给元素的 style
    for (let k in styles) {
      ele.style[k] = styles[k]
    }
  }
}
